#include "head.h"
#include "func.h"
#include <crypt.h>
#include <shadow.h>

//从加密密码中获取盐值                                                                     
void getsalt(char *salt, const char *passwd)
{
    int i = 0;
    int dollar_count = 0;
    while (passwd[i]) {
        if (passwd[i] == '$') {
            dollar_count++;
            if (dollar_count == 4) { // 找到第4个$
                i++;  // 位置移动到第4个$后面
                break;
            }
        }
        i++;
    }

    if (dollar_count == 4) {
        strncpy(salt, passwd, i);
        salt[i] = '\0';  // 注意字符串结尾
    } else {
        strcpy(salt, passwd); // 容错处理
    }
}

//验证客户端的用户名和密码
int login_varify(socket_t fd, ptrain_t pT)
{
    train_t train = *pT;
    char user_name[128] = "";
    char user_passwd[128] = "";
    //接收用户名
    memset(&train, 0, sizeof(train));
    recv(fd, &train._data_len, sizeof(int), 0);
    recv(fd, train._data, train._data_len, 0);
    /* printf("recv_username: %s\n", train._data); */
    strncpy(user_name, train._data, sizeof(user_name) - 1);

    //接收密码
    memset(&train, 0, sizeof(train));
    recv(fd, &train._data_len, sizeof(int), 0);
    recv(fd, train._data, train._data_len, 0);
    /* printf("recv_passwd: %s\n", train._data); */
    strncpy(user_passwd, train._data, sizeof(user_passwd) - 1);

    //验证
    //检查用户是否存在
    struct spwd *sp = NULL;    //用来获取/etc/shadow中的加密密码
    char salt[512] = ""; //用来获取用户的盐值

    sp = getspnam(user_name);
    if (NULL == sp) {
        printf("user_name is not exist!\n");
        return -1;
    }
    else {
        //获取salt
        getsalt(salt, sp->sp_pwdp);
        //比对
        if (!strcmp(sp->sp_pwdp, crypt(user_passwd, salt))) {
            printf("[%s] login success!\n", user_name);
            return 0;
        }
        else {
            printf("user_passwd is error!\n");
            return -1;
        }
    }
}
